<!--
 * @Author: weidewei
 * @Date: 2025-10-30 13:44:59
 * @LastEditors: weidewei
 * @LastEditTime: 2025-10-30 15:16:05
 * @Description: 
 * @FilePath: \2025-front-face\review-knowledge\20251029\复习上下文和作用域链.html
-->
<script>
  // 1. 基础变量提升
  function test1() {
    console.log(a); // undefined
    console.log(b); // undefined
    var a = 1;
    var b = function () {};
    console.log(a); // 1
    console.log(b); // function b
  }
  test1();

  // 2. 函数声明提升
  function test2() {
    console.log(foo); // function foo
    console.log(bar); // undefined

    function foo() {
      return "foo";
    }
    var bar = function () {
      return "bar";
    };
    console.log(foo()); // undefined 错 答案：'foo' 以为函数声明后就丢掉了该方法
    console.log(bar()); // 'bar'
  }
  test2();

  // 3. 同名变量与函数
  function test3() {
    console.log(a); // function a

    var a = 1;
    function a() {}

    console.log(a); // 1
  }
  test3();

  // 4. 参数与变量同名
  function test4(x, y, z) {
    console.log(x, y, z); // 1,2,function z
    var x = "new x";
    var y = function y() {};
    function z() {}
    console.log(x, y, z); // 'new x',function y,undefined 错 答案：'new x',function y,function z
  }
  test4(1, 2, 3);

  // 5. 立即执行函数的影响
  function test5(a, b) {
    console.log(a, b); // param a,param b
    var a = "variable a";

    (function a() {
      console.log("IIFE a:", a); // variable a 错 答案：function a 具名函数表达式 (function a() {}) 和 (function b() {}) 创建了新的作用域，在这些IIFE内部，函数名 a 和 b 绑定到各自的函数对象，遮蔽了外部同名变量
    })();

    (function b() {
      console.log("IIFE b:", b); // variable b 错 答案：function b
    })();

    console.log(a, b); // variable a,param b
  }
  test5("param a", "param b");

  // 6. var vs let
  function test6() {
    console.log(a); // undefined

    if (true) {
      var a = "var a";
      let b = "let b";
      console.log(a, b); // var a,let b
    }

    console.log(a); // var a
    console.log(b); // undefined 错 答案：报错
  }
  test6();

  // 7. 函数声明在块中
  function test7() {
    console.log(foo); // 报错 错 答案：undefined 在非严格模式下，块内的函数声明行为类似 var 提升

    if (true) {
      function foo() {
        return "block foo";
      }
    }

    console.log(foo); //  报错 答案：function foo
  }
  test7();

  // 8. 多层作用域
  function test8(a) {
    console.log(a); // outer param

    function inner(b) {
      console.log(a, b); // undefined,undefined 错 答案：undefined,inner param
      var a = "inner a"; // 这里的赋值只影响自己的作用域
      console.log(a, b); // inner a,inner param
    }

    inner("inner param");
    console.log(a); // inner a 错 答案：outer param
  }
  test8("outer param");

  // 9. 闭包与变量提升
  function test9() {
    var functions = [];

    for (var i = 0; i < 3; i++) {
      functions.push(function () {
        console.log(i);
      });
    }

    functions[0](); // 3
    functions[1](); // 3
    functions[2](); // 3

    // 如果用let会怎样？0,1,2
  }
  test9();

  // 10. 终极挑战题
  function challenge(a) {
    console.log(a, b, c); // function a,function b,function c

    var a = "variable a";
    var b = function b() {};
    var c = "variable c";

    function a() {}
    function b() {}
    function c() {}

    console.log(a, b, c); // function a,function b,function c 错 答案：variable a,function b,variable c

    (function () {
      console.log(a, b, c); // undefined,function b,function c 错 答案：undefined，function b,variable c
      var a = "IIFE a";
      console.log(a, b, c); // IIFE a,function b,function c 错 答案：IIFE a,function b,variable c
    })();

    console.log(a, b, c); // function a,function b,function c 错 答案：variable a，function b,variable c
  }
  challenge("param a");
</script>
